package domain

import (
	"database/sql/driver"
	"fmt"
	"time"
)

type BaseStruct struct {
	CreatedAt time.Time `xorm:"created"`      // 创建时间
	CreatedBy string    `xorm:"varchar(64)"`  // 创建者
	UpdatedAt time.Time `xorm:"updated"`      // 更新时间
	UpdatedBy string    `xorm:"varchar(64)"`  // 更新者
	DeletedAt time.Time `xorm:"deleted"`      // 删除时间
	Remark    string    `xorm:"varchar(500)"` // 备注
}

type BaseJson struct {
	CreatedAt Time   `json:"createdAt,omitempty"`
	CreatedBy string `json:"createdBy,omitempty"`
	UpdatedAt Time   `json:"updatedAt,omitempty"`
	UpdatedBy string `json:"updatedBy,omitempty"`
	Remark    string `json:"remark,omitempty"`
}

// ParamTime 时间范围
type ParamTime struct {
	BeginTime string `xorm:"-" json:"beginTime,omitempty"`
	EndTime   string `xorm:"-" json:"endTime,omitempty"`
}

type PageDto struct {
	Ids      []int64 `xorm:"-" json:"ids"`
	PageNum  int     `xorm:"-" json:"pageNum"`
	PageSize int     `xorm:"-" json:"pageSize"`
	LastId   int64   `xorm:"-" json:"lastId"`
	Desc     bool    `xorm:"-" json:"desc"`
}

// 分页
type PageVo struct {
	PageNum  int   `json:"pageNum"`
	PageSize int   `json:"pageSize"`
	LastId   int64 `json:"lastId,omitempty"`
	Total    int64 `json:"total"`
	Rows     any   `json:"rows"`
}

// 自定义时间
const timeFormat = "2006-01-02 15:04:05"
const timezone = "Asia/Shanghai"

type Time time.Time // 全局定义

func (t Time) MarshalJSON() ([]byte, error) {
	b := make([]byte, 0, len(timeFormat)+2)
	b = append(b, '"')
	b = time.Time(t).AppendFormat(b, timeFormat)
	b = append(b, '"')
	return b, nil
}

func (t *Time) UnmarshalJSON(data []byte) (err error) {
	now, err := time.ParseInLocation(`"`+timeFormat+`"`, string(data), time.Local)
	*t = Time(now)
	return
}

func (t Time) String() string {
	return time.Time(t).Format(timeFormat)
}

func (t Time) Local() time.Time {
	loc, _ := time.LoadLocation(timezone)
	return time.Time(t).In(loc)
}

func (t Time) Value() (driver.Value, error) {
	var zeroTime time.Time
	var ti = time.Time(t)
	if ti.UnixNano() == zeroTime.UnixNano() {
		return nil, nil
	}
	return ti, nil
}

func (t *Time) Scan(v interface{}) error {
	value, ok := v.(time.Time)
	if ok {
		*t = Time(value)
		return nil
	}
	return fmt.Errorf("can not convert %v to timestamp", v)
}
